using System;
using System.Collections.Generic;
using System.Windows.Forms;
using FireStarter.Base;
using FireStarterModeller.BO;
using FireStarterModeller.Logic;
using FireStarterModeller.Test.Logic;
using FireStarterModeller.UI;
using FireStarterModeller.UI.ViewEditor;
using Habanero.Base;
using Habanero.BO;
using Habanero.Faces.Base;
using Habanero.Faces.Win;
using Habanero.Util;
using NUnit.Framework;
using Rhino.Mocks;
using DockStyle=Habanero.Faces.Base.DockStyle;

namespace FireStarterModeller.Test.UI.ViewEditor
{
    [TestFixture]
    public class TestXmlUIViewsEditorControl
    {
        [TestFixtureSetUp]
        public void SetupFixture()
        {
            UITestUtils.SetupFixture();
        }

        [SetUp]
        public virtual void SetupTest()
        {
            UITestUtils.SetupTest();
        }

        private static IControlFactory GetControlFactory()
        {
            return GlobalUIRegistry.ControlFactory;
        }

//        DMToEntityClassDefsConverter converter = new DMToEntityClassDefsConverter();
//        IClassDef classDef = converter.Convert(dmClass);
//        IUIXmlEditorControl xmlEditorControl = new UIXmlEditorControl(_controlFactory, new DMToClassDefsXmlConverter(), new XmlTextEditor());
//        IUIPreviewControl previewControl = new UIPreviewControl(_controlFactory);

//        UIViewsEditorControl editorControl = new UIViewsEditorControl(_controlFactory, xmlEditorControl, previewControl,  new UIViewSelectorControl(_controlFactory),
//                                                                      classDef);
//        editorControl.EditUIViews(dmClass.UIViews);

        [Test]
        public void Test_Construct()
        {
            CrossThreadRunner runner = new CrossThreadRunner();
            runner.RunInSTA(
                delegate
                    {
                        //---------------Set up test pack-------------------
                        IControlFactory controlFactory = GetControlFactory();
                        IFireStarterFormsController formsController = new FireStarterFormsControllerStub(controlFactory);
                        //---------------Assert Precondition----------------
                        Assert.IsNotNull(controlFactory);
                        //---------------Execute Test ----------------------
                        XmlUIViewsEditorControl xmlUIViewsEditorControl = new XmlUIViewsEditorControl(controlFactory, formsController);
                        //---------------Test Result -----------------------
                        Assert.AreSame(controlFactory, xmlUIViewsEditorControl.ControlFactory);
                        Assert.AreSame(formsController, xmlUIViewsEditorControl.FormsController);
                        Assert.IsInstanceOf(typeof (IUIViewsEditor), xmlUIViewsEditorControl);
                        Assert.IsInstanceOf(typeof (IControlHabanero), xmlUIViewsEditorControl);
                    });
        }

        [Test]
        public void Test_Layout()
        {
            //---------------Set up test pack-------------------
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            XmlUIViewsEditorControl xmlUIViewsEditorControl = CreateXmlUIViewsEditorControl();
            //---------------Test Result -----------------------
            Assert.AreEqual(1, xmlUIViewsEditorControl.Controls.Count);
            Assert.IsInstanceOf(typeof (UIViewsEditorControl), xmlUIViewsEditorControl.Controls[0]);
            UIViewsEditorControl uiViewsEditorControl = (UIViewsEditorControl) xmlUIViewsEditorControl.Controls[0];
            Assert.AreSame(uiViewsEditorControl, xmlUIViewsEditorControl.UIViewsEditorControl);
            Assert.IsNotNull(uiViewsEditorControl.PreviewControl);
            Assert.IsNotNull(uiViewsEditorControl.PreviewFormButton);
            Assert.IsNotNull(uiViewsEditorControl.PreviewGridButton);
            Assert.IsNotNull(uiViewsEditorControl.SelectorControl);
            Assert.IsNotNull(uiViewsEditorControl.XMLEditorControl);
            Assert.IsNotNull(uiViewsEditorControl.DMClassToClassDefConverter);
            Assert.IsInstanceOf(typeof(DMToEntityClassDefsConverter), uiViewsEditorControl.DMClassToClassDefConverter);
            Assert.IsFalse(xmlUIViewsEditorControl.Enabled);
        }

        [Test]
        public void Test_EditUIViews_WhenDMClassIsNull_ShouldDisable()
        {
            //---------------Set up test pack-------------------
            XmlUIViewsEditorControl xmlUIViewsEditorControl = CreateXmlUIViewsEditorControl();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            xmlUIViewsEditorControl.EditUIViews(null);
            //---------------Test Result -----------------------
            Assert.IsFalse(xmlUIViewsEditorControl.Enabled);
        }
        [Test]
        public void Test_EditUIViews_WhenDMClassIsNotNull_ShouldEnable()
        {
            //---------------Set up test pack-------------------
            XmlUIViewsEditorControl xmlUIViewsEditorControl = CreateXmlUIViewsEditorControl();
            DMClass dmClass = TestUtilsLogic.CreateClassWithOneGuidProperty();
            //---------------Assert Precondition----------------
            Assert.IsFalse(xmlUIViewsEditorControl.Enabled);
            //---------------Execute Test ----------------------
            xmlUIViewsEditorControl.EditUIViews(dmClass);
            //---------------Test Result -----------------------
            Assert.IsTrue(xmlUIViewsEditorControl.Enabled);
        }

        [Test]
        public void Test_EditUIViews_WhenDMClassChangesToNull_ShouldDisable()
        {
            //---------------Set up test pack-------------------
            XmlUIViewsEditorControl xmlUIViewsEditorControl = CreateXmlUIViewsEditorControl();
            DMClass dmClass = TestUtilsLogic.CreateClassWithOneGuidProperty();
            xmlUIViewsEditorControl.EditUIViews(dmClass);
            //---------------Assert Precondition----------------
            Assert.IsTrue(xmlUIViewsEditorControl.Enabled);
            //---------------Execute Test ----------------------
            xmlUIViewsEditorControl.EditUIViews(null);
            //---------------Test Result -----------------------
            Assert.IsFalse(xmlUIViewsEditorControl.Enabled);
        }

        [Test]
        public void Test_EditUIViews_WhenDMClassNotNull_ShouldCallThroughToUIViewsEditorControl()
        {
            //---------------Set up test pack-------------------
            XmlUIViewsEditorControl xmlUIViewsEditorControl = CreateXmlUIViewsEditorControl();
            DMClass dmClass = TestUtilsLogic.CreateClassWithOneGuidProperty();
            IUIViewsEditorControl uiViewsEditorControl = MockRepository.GenerateStub<IUIViewsEditorControl>();
            xmlUIViewsEditorControl.UIViewsEditorControl = uiViewsEditorControl;
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            xmlUIViewsEditorControl.EditUIViews(dmClass);
            //---------------Test Result -----------------------
            uiViewsEditorControl.AssertWasCalled(control => control.EditUIViews(Arg<BusinessObjectCollection<UIView>>.Is.Same(dmClass.UIViews)));
        }
        
        [Test]
        [Ignore("For visual testing purposes")]
        public void Test_Visually()
        {
            //---------------Set up test pack-------------------
            new CrossThreadRunner().RunInSTA(delegate
            {
                DMClass dmClass = TestUtilsLogic.CreateClassWithTwoUIViews();
                XmlUIViewsEditorControl xmlUIViewsEditorControl = CreateXmlUIViewsEditorControl();
                xmlUIViewsEditorControl.EditUIViews(dmClass);
                //---------------Assert Precondition----------------
                //---------------Execute Test ----------------------
                TestUtilsUI.ShowInVisualTestingForm(GetControlFactory(), xmlUIViewsEditorControl, DockStyle.Fill);
            });
        }

        [Test]
        public void Test_SaveChangesButtonClick()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsLogic.CreateClassWithOneUIView();
            XmlUIViewsEditorControl xmlUIViewsEditorControl = CreateXmlUIViewsEditorControl();
            xmlUIViewsEditorControl.EditUIViews(dmClass);

            //---------------Assert PreConditions---------------       
            Assert.AreEqual(1, dmClass.UIViews.Count);
            UIView oldUIView = dmClass.UIViews[0];
            string oldUIViewName = oldUIView.ViewName;
            Assert.AreEqual(1, oldUIView.UIFormInfo.UITabs.Count);
            Assert.AreEqual(1, oldUIView.UIGridInfo.UIColumns.Count);
            //---------------Execute Test ----------------------
            xmlUIViewsEditorControl.UIViewsEditorControl.ApplyChangesButton.PerformClick();
            //---------------Test Result -----------------------
            Assert.AreEqual(1, dmClass.UIViews.Count);
            UIView newUIView = dmClass.UIViews[0];
            Assert.AreNotSame(oldUIView, newUIView);
            Assert.AreEqual(oldUIViewName, newUIView.ViewName);
            Assert.AreEqual(1, newUIView.UIFormInfo.UITabs.Count);
            Assert.AreEqual(1, newUIView.UIGridInfo.UIColumns.Count);
            Assert.AreSame(xmlUIViewsEditorControl.UIViewSelectorControl.SelectedUIView, newUIView);
            Assert.AreSame(xmlUIViewsEditorControl.UIXmlEditorControl.CurrentUIView, newUIView);

            //---------------Tear Down -------------------------          
        }

        private static XmlUIViewsEditorControl CreateXmlUIViewsEditorControl()
        {
            IControlFactory controlFactory = GetControlFactory();
            FireStarterFormsController formsController = new FireStarterFormsControllerStub(controlFactory);
            XmlUIViewsEditorControl xmlUIViewsEditorControl = new CrossThreadRunner().RunInSTA(() => new XmlUIViewsEditorControl(controlFactory, formsController));
            return xmlUIViewsEditorControl;
        }
    }
}